今天我們將延續前幾天的案例分享,完成整個 CD(持續部署)流程,並把範例前端部署到 Windows Server 的 IIS 上。這代表著,我們正式完成了將 CI/CD 流程透過 Azure DevOps 的目標。
在左側導航欄點擊 「 Release 」 以進入 Release 管理頁面。
點擊頁面中央的藍色按鈕 「 New Pipeline 」,開始建立新的 pipeline。
這裡我們選擇 「 Empty job 」,不使用任何模板,直接從空白開始建立。
點擊頁面上的 「 Add an artifact 」,選擇 artifact 來源。
Azure Pipelines 支援各種儲存庫、服務和 CI/CD 平台。建立版本時,您可以指定工件來源的版本。預設情況下,版本使用來源工件的最新版本。您也可以透過指定標籤、特定版本來選擇使用特定分支的最新版本,或允許使用者在建立版本時指定版本。
Reference - Artifact sources in Classic release pipelines
選擇好 Source 後,Azure DevOps 會自動抓取最新的版本,點擊 「 Add 」完成工件的新增。
點擊剛新增的工件右上角的閃電符號以進入觸發設定。
啟用自動觸發後,每當有新版本可用時都會自動建立 Release。
啟用成功後,閃電符號上會顯示勾選符號,表示自動觸發器已設置成功。
此選項有兩個常見的功能:
點擊 Stage 1 方框左側的紅框以開啟該選單
確認該 Stage 被設置為自動部署,確保部署流程順暢。
如下圖紅框所示,目前該 Stage 有一個 Job 及 0 個 task,我們可以透過點擊,進入細節設定。
在設定頁面將 Stage 名稱更改為 "Azure Server 1" 以便識別。
點擊三連點可以看到,有三種不同類型的 job 可以選擇:Agent job、Deployment group job 和 Agentless job,預設會是透過 Azure Agent 所執行的 Job ( Add an agent job )。
Job 是任務的邏輯分組,定義執行任務的運行環境。以下是一些關鍵設定:
將 Job 名稱更改為 "deploy",使其更具描述性。
在 Agent Pool 中選擇 "30dayPool" 作為運行的 Agent Pool。
透過 Demands 的設定,我們可以為每個不同的 Job 透過 Filter 的方式使特定的 Job 僅供 Agent Pool 內特定的 Agent 運行,其 filter 的方式請參考這篇連結。
Execution Plan 部分可以為代理程式設定在執行任務時的相關策略和參數:
Additional Options 部分提供了一些額外的選項,用於更靈活地控制作業的執行行為及其條件:
Service connections 是 Azure Pipelines 與用於執行作業中的任務的外部或遠端服務之間經過驗證的連線。部分 Pipeline 所使用的 task 可使用該認證方法,因此先建立起來,稍後會使用到。
點選 Project settings 裡的 Service connections。
點擊右上角的 New service connection 按鍵。
建立 SSH 使用的 connection。
填入必要資訊。
完成後,會顯示在頁面上。
這邊紀錄幾個對我來說比較棘手的點:
還記得昨天 CI 過程中我們為 artifact name 的命名規則,將其補上其規則。
steps:
- task: DownloadPipelineArtifact@2
displayName: 'Download Pipeline Artifact'
inputs:
artifactName: 'quasar-dist-$(Build.BuildNumber)'
CopyFilesOverSSH 這個 Task 會預設使用你所建立的 service connection 裡的連線帳號的家目錄底下。
有嘗試透過這篇 What is the home directory on Windows Subsystem for Linux? 去切換到 D 槽,但是我測試到目前只能使用到 C:\,供參考。
另外:其中的 sshEndpoint 就是透過 service connection 所提供。
steps:
- task: CopyFilesOverSSH@0
displayName: 'Securely copy files to the remote machine'
inputs:
sshEndpoint: 'server-a'
sourceFolder: '$(Pipeline.Workspace)/spa'
targetFolder: /app
isWindowsOnTarget: true
enabled: true
上面的 script 最終會 download 在 pipeline folder 裡的 artifact 前端靜態資源 copy 到目標 server 的 C:\app 底下。
powershell -ExecutionPolicy Bypass -File C:\Tools\deployAppPool.ps1
powershell -ExecutionPolicy Bypass -File C:\Tools\deployAppSite.ps1
可另外搭配 Pipeline variables 做使用,透過 scope 的設定,讓不同的 stage 能帶進不同的參數,這個使用方法,之後有機會再另外寫一篇出來講。
# 导入 WebAdministration 模块
Import-Module WebAdministration
# 定义应用程序池名称
$AppPoolName = "MyAppPool"
# 检查应用程序池是否存在,如果不存在则创建
if (-not (Get-Item IIS:\AppPools\$AppPoolName -ErrorAction SilentlyContinue)) {
# 创建新的应用程序池
New-Item IIS:\AppPools\$AppPoolName
# 设置应用程序池的属性
Set-ItemProperty IIS:\AppPools\$AppPoolName -Name "managedRuntimeVersion" -Value "v4.0"
Set-ItemProperty IIS:\AppPools\$AppPoolName -Name "processModel.identityType" -Value "ApplicationPoolIdentity"
Write-Host "应用程序池 '$AppPoolName' 已创建。"
} else {
Write-Host "应用程序池 '$AppPoolName' 已存在。"
}
# 导入 WebAdministration 模块
Import-Module WebAdministration
# 定义变量
$SiteName = "MyWebsite"
$AppPoolName = "MyAppPool"
$PhysicalPath = "C:\inetpub\wwwroot\MyWebsite"
$BindingProtocol = "http"
$Port = 8888
$IPAddress = "*"
$HostHeader = ""
# 检查物理路径是否存在,不存在则创建
if (-not (Test-Path $PhysicalPath)) {
New-Item -Path $PhysicalPath -ItemType Directory -Force
}
# 检查网站是否存在,如果不存在则创建
if (-not (Get-Item IIS:\Sites\$SiteName -ErrorAction SilentlyContinue)) {
# 创建新的网站
New-Item IIS:\Sites\$SiteName -PhysicalPath $PhysicalPath -Bindings @{protocol=$BindingProtocol; bindingInformation="$IPAddress`:$Port`:$HostHeader"} -ApplicationPool $AppPoolName
Write-Host "网站 '$SiteName' 已创建并绑定到端口 $Port。"
} else {
Write-Host "网站 '$SiteName' 已存在。"
}
# 导入 WebAdministration 模块
Import-Module WebAdministration
Param(
[string]$SiteName = "MyWebsite",
[string]$AppPoolName = "MyAppPool",
[string]$PhysicalPath = "C:\inetpub\wwwroot\MyWebsite",
[string]$BindingProtocol = "http",
[int]$Port = 8888,
[string]$IPAddress = "*",
[string]$HostHeader = ""
)
# 检查物理路径是否存在,不存在则创建
if (-not (Test-Path $PhysicalPath)) {
New-Item -Path $PhysicalPath -ItemType Directory -Force
}
# 检查网站是否存在,如果不存在则创建
if (-not (Get-Item IIS:\Sites\$SiteName -ErrorAction SilentlyContinue)) {
# 创建新的网站
New-Item IIS:\Sites\$SiteName -PhysicalPath $PhysicalPath -Bindings @{protocol=$BindingProtocol; bindingInformation="$IPAddress`:$Port`:$HostHeader"} -ApplicationPool $AppPoolName
Write-Host "网站 '$SiteName' 已创建并绑定到端口 $Port。"
} else {
Write-Host "网站 '$SiteName' 已存在。"
}
powershell -ExecutionPolicy Bypass -File 'C:\Tools\deployAppSite.ps1' `
-SiteName '$(SiteName)' `
-AppPoolName '$(AppPoolName)' `
-PhysicalPath '$(PhysicalPath)' `
-BindingProtocol '$(BindingProtocol)' `
-Port $(Port) `
-IPAddress '$(IPAddress)' `
-HostHeader '$(HostHeader)'
可以透過 Release 的頁面,新增 release。
可以選取你想要的 version,並且依據當次任務需求決定是否有需要 trigger step。
連續分享技術文章 30 天不間斷的挑戰就要在今天結束了,開心之餘除了將陸續將上述未完成的章節研究完,也期許自己能夠在接下來的日子裡,產出一些有參考價值的文章,以時時充滿好奇心的心態,去探索一切,下次見。